Skip to content

指针

指针也就是内存地址,指针变量是用来存放内存地址的变量。就像其他变量或常量一样,您必须在使用指针存储其他变量地址之前,对其进行声明。

数据存储在内存中,内存又被分为一块一块的,每一块都有一个特有的编号。而这个编号可以暂时理解为指针,就像房屋的编号。

例如:现在李四想要去找张三,那么就要找到张三家里的对应门牌号,这里的门牌号可以理解为是指针;
image.png

指针变量声明的一般形式为:

c
type *name;

type 是指针的基类型,它必须是一个有效的 C 数据类型,例如 int,double,char 等。 name 是指针变量的名称。在这个语句中,星号是用来指定一个变量是指针。
以下是有效的指针声明:

c
	int *p1;    //一个整数类型的指针
	char *p2;   //一个字符类型的指针
	double *p3; //一个double类型的指针
	float * p4; //一个float类型的指针

不同数据类型的指针之间唯一的不同是,指针所指向的变量或常量的数据类型不同。

如何使用指针?

指针变量的初始化

  • 语法形式:

存储类型 数据类型 *指针名=初始地址;

例如:

c
	int a = 100;
	int *p1 =  &a;
  • 示例:
指针变量 示例代码
cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
	int a = 100;
	int *p1 =  &a;
	printf("a的地址:%p",&a);
	cout << endl;
	printf("p1的值:%p",p1);
	return 0;
}

运行结果:

c
a的地址:00000000006ffe14
p1的值:00000000006ffe14

分析

1、表示创建了一个整数类型的指针变量 p1,指向整数变量 a;
2、这里打印出来的值并不固定,但是 a 的地址跟 p1 的值一定是相等的。
图解如下: image.png

注意

用变量地址作为初值时,该变量必须在指针初始化之前已声明过,且变量类型应与指针类型一致。

指针变量的赋值运算

  • 语法形式:

指针名=地址

  • 示例
指针变量的赋值 示例代码
cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
	int a = 100;
	int b = 300;
	int *p1 =  &a;
	p1 = &b;
	printf("a的地址:%p\n",&a);
	printf("b的地址:%p\n",&b);
	printf("p1的值:%p\n",p1);
	return 0;
}

运行结果:

c
a的地址:00000000006ffe14
b的地址:00000000006ffe10
p1的值:00000000006ffe10

分析

1、这里的数值大小不重要,重要的是相等与否;
2、p1 变量本来装的是 a 的地址,经过 p1 = &b,之后装的是 b 的地址了;

警告

向指针变量赋的值必须是地址常量或变量,不能是普通整数

下面这种写法是错误的
p1 = 100;

NULL 指针

在变量声明的时候,如果没有确切的地址可以赋值,为指针变量赋一个 NULL 值是一个良好的编程习惯。赋为 NULL 值的指针被称为空指针

NULL 指针是一个定义在标准库中的值为零的常量。请看下面的程序:

cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
	int  *p1 = NULL;
   	printf("p1 的值是 %p", p1 );
	return 0;
}

分析

运行结果
p1 的值是 0x0

内存地址 0 有特别重要的意义,它表明该指针不指向一个可访问的内存位置。但按照惯例,如果指针包含空值(零值),则假定它不指向任何东西。 :::

指针的相关操作

  • 修改指针变量所指向的变量的值

通过使用一元运算符 * 来进行操作

修改指针变量所指向的变量的值 示例代码
cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
	int a = 100;
	int *p1 =  &a;
	printf("a的地址:%p",&a);
	cout << endl;
	printf("p1的值:%p",p1);
	cout << endl;
	printf("*p1 变量的值: %d", *p1 );
	cout << endl;
	printf("修改前:a 变量的值: %d", a );
	cout << endl;
	*p1 = 200;
	printf("修改后:a 变量的值: %d", a );
	return 0;
}

运行结果:

c
a的地址:00000000006ffe14
p1的值:00000000006ffe14
*p1 变量的值: 100
修改前:a 变量的值: 100
修改后:a 变量的值: 200

分析

同样的,这里 a 的地址跟 p1 的值是多少不重要,重要的是相等;
在这里*p1 可以理解为等价于 a,修改 *p1 相当于修改 a 变量的值

内存管理

C++中,可以将newdelete与指针结合起来,实现细粒度管理内存。

管理内存 示例代码
cpp
#include<bits/stdc++.h>
using namespace std;
int main()
{
	int size;
	cout<<"输入数组大小: "<<endl;
	cin >> size;
	int *arr = new int[size]; //动态声明内存空间
	for(int i=0;i<size;i++)
	{
		cin>>arr[i];
	}
	for(int i=0;i<size;i++)
	{
		cout<<arr[i]<<",";
	}
	delete arr;  // 删除内存空间
	for(int i=0;i<size;i++)
	{
		cout<<arr[i]<<",";
	}
	return 0;
}